package designpattern.aop;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
 * AOP代理实现
 * @author liuboen
 *
 */
public class PoxyInvocation implements InvocationHandler {
	/**
	 * 代理处理过程
	 */
	private Object proxy;
	/**
	 * 原对象
	 */
	private Object delegate;
	/**
	 * 执行原方法前执行代理的方法名
	 */
	private String startMethod;
	/**
	 * 执行原方法后执行代理的方法名
	 */
	private String endMethod;
	
	Class<? extends Object> clazz = null;
	/**
	 * 通过当前对象生成代理对象
	 * @param delegate
	 * @param proxy
	 * @param startMethod
	 * @param endMethod
	 * @return
	 */
	public Object bind(Object delegate, Object proxy , String startMethod , String endMethod) {
		this.proxy = proxy;
		this.delegate = delegate;
		this.startMethod = startMethod;
		this.endMethod = endMethod;
		clazz = this.proxy.getClass();
		return Proxy.newProxyInstance(this.delegate.getClass().getClassLoader(), this.delegate.getClass().getInterfaces(), this);
	}

	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		Object result = null;
		try {
			//执行代理方法,在执行原方法前
			invokeProxy(startMethod);
			//执行原方法
			result = method.invoke(this.delegate, args);	
			//执行代理方法,在执行原方法后
			invokeProxy(endMethod);

		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}

	/**
	 * 执行代理方法
	 * @param proxyMethodName
	 * @throws NoSuchMethodException
	 * @throws SecurityException
	 * @throws IllegalAccessException
	 * @throws IllegalArgumentException
	 * @throws InvocationTargetException
	 */
	private void invokeProxy(String proxyMethodName) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{
		if (proxyMethodName != null) {
			Method end = clazz.getDeclaredMethod(proxyMethodName);
			end.invoke(this.proxy);
		}

	}
}
